package korwin;

import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.event.KeyEvent;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.URL;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.imageio.ImageIO;

public class Korwin {
    
    // Health of the helicopter.
    private final int healthInit = 100;
    public int health;
    public int xCoordinate;
    public int yCoordinate;
    private double movingXspeed;
    public double movingYspeed;
    private double acceleratingXspeed;
    private double acceleratingYspeed;
    private double stoppingXspeed;
    private double stoppingYspeed;
    
    // Helicopter rockets.
    private final int numberOfRocketsInit = 80;
    public int numberOfRockets;
    
    // Helicopter machinegun ammo.
    private final int numberOfAmmoInit = 200;
    public int numberOfAmmo;
    
    // Images of helicopter and its propellers.
    public BufferedImage bodyImg;
    private BufferedImage rearAnimImg;
    public BufferedImage korwinFaceImg;
    public BufferedImage frontImg;
    
    // Animation of the helicopter propeller.
    private Animation rearAnim;
    // Offset for the propeler. We add offset to the position of the position of helicopter.
    private int offsetXRearPropeller;
    private int offsetYRearPropeller;
    public int offsetXKorwinFace;
    public int offsetYKorwinFace;
    public int offsetXFrontImg;
    public int offsetYFrontImg;
    
    // Offset of the helicopter rocket holder.
    private int offsetXRocketHolder;
    private int offsetYRocketHolder;
    // Position on the frame/window of the helicopter rocket holder.
    public int rocketHolderXcoordinate;
    public int rocketHolderYcoordinate;
    
    // Offset of the helicopter machine gun. We add offset to the position of the position of helicopter.
    private int offsetXAnchor;
    private int offsetYAnchor;
    // Position on the frame/window of the helicopter machine gun.
    public int revolverXAnchor;
    public int revolverYAnchor;
    public double revolverXAim;
    public double revolverYAim;
    
    public int bulletsAvailble;
    
    /**
     * Creates object of player.
     * 
     * @param xCoordinate Starting x coordinate of helicopter.
     * @param yCoordinate Starting y coordinate of helicopter.
     */
    public Korwin(int xCoordinate, int yCoordinate)
    {
        this.xCoordinate = xCoordinate;
        this.yCoordinate = yCoordinate;
        
        LoadContent();
        Initialize();
    }
    
    
    /**
     * Set variables and objects for this class.
     */
    private void Initialize()
    {
        this.health = healthInit;
        this.bulletsAvailble = 6;
        this.numberOfRockets = numberOfRocketsInit;
        this.numberOfAmmo = numberOfAmmoInit;
        
        this.movingXspeed = 0;
        this.movingYspeed = 0;
        this.acceleratingXspeed = 0.3;
        this.acceleratingYspeed = 0.3;
        this.stoppingXspeed = 0.1;
        this.stoppingYspeed = 0.1;
     
        this.offsetXRearPropeller = -8;
        this.offsetYRearPropeller = 15;
        this.offsetXKorwinFace = 95;
        this.offsetYKorwinFace = -19;
        this.offsetXFrontImg = 49;
        this.offsetYFrontImg = -61;
        
        this.offsetXRocketHolder = 138;
        this.offsetYRocketHolder = 40;
        this.rocketHolderXcoordinate = this.xCoordinate + this.offsetXRocketHolder;
        this.rocketHolderYcoordinate = this.yCoordinate + this.offsetYRocketHolder;
        
        this.offsetXAnchor = bodyImg.getWidth() - 40;
        this.offsetYAnchor = bodyImg.getHeight();
        this.revolverXAnchor = this.xCoordinate + this.offsetXAnchor;
        this.revolverYAnchor = this.yCoordinate + this.offsetYAnchor;
        this.revolverXAim = revolverXAnchor + offsetXAnchor;
        this.revolverYAim = revolverYAnchor + offsetYAnchor;
    }
    
    /**
     * Load files for this class.
     */
    private void LoadContent()
    {
        try 
        {
            URL helicopterBodyImgUrl = this.getClass().getResource("/korwin/resources/images/1_helicopter_body.png");
            bodyImg = ImageIO.read(helicopterBodyImgUrl);
            
            URL helicopterRearPropellerAnimImgUrl = this.getClass().getResource("/korwin/resources/images/1_rear_propeller_anim_blur.png");
            rearAnimImg = ImageIO.read(helicopterRearPropellerAnimImgUrl);

            URL korwinFaceImgUrl = this.getClass().getResource("/korwin/resources/images/korwin.png");
            korwinFaceImg = ImageIO.read(korwinFaceImgUrl);
            
            URL frontImgUrl = this.getClass().getResource("/korwin/resources/images/submarine2.png");
            frontImg = ImageIO.read(frontImgUrl);
        
        } 
        catch (IOException ex) {
            Logger.getLogger(Korwin.class.getName()).log(Level.SEVERE, null, ex);
        }
        
        // Now that we have images of propeller animation we initialize animation object.
        rearAnim = new Animation(rearAnimImg, 54, 54, 4, 20, true, xCoordinate + offsetXRearPropeller, yCoordinate + offsetYRearPropeller, 0);
        
    }
    
    
    /**
     * Resets the player.
     * 
     * @param xCoordinate Starting x coordinate of helicopter.
     * @param yCoordinate Starting y coordinate of helicopter.
     */
    public void Reset(int xCoordinate, int yCoordinate)
    {
        this.health = healthInit;
        
        this.numberOfRockets = numberOfRocketsInit;
        this.numberOfAmmo = numberOfAmmoInit;
        
        this.xCoordinate = xCoordinate;
        this.yCoordinate = yCoordinate;
        
        this.revolverXAnchor = this.xCoordinate + this.offsetXAnchor;
        this.revolverYAnchor = this.yCoordinate + this.offsetYAnchor;
        
        this.movingXspeed = 0;
        this.movingYspeed = 0;
    }
    
    
    /**
     * Checks if player is shooting. It also checks if player can 
     * shoot (time between bullets, does a player have any bullet left).
     * 
     * @param gameTime The current elapsed game time in nanoseconds.
     * @return true if player is shooting.
     */
    public boolean isShooting(long gameTime)
    {
        // Checks if left mouse button is down && if it is the time for a new bullet.
        if( Canvas.mouseButtonState(MouseEvent.BUTTON1) && 
            ((gameTime - Bullet.timeOfLastCreatedBullet) >= Bullet.timeBetweenNewBullets) &&
            this.bulletsAvailble > 0) 
        {
            return true;
        } else
            return false;
    }
    
    public boolean isReloading()
    {
        if( Canvas.keyboardKeyState(KeyEvent.VK_SPACE) && this.bulletsAvailble < 6) 
        {
        	this.numberOfAmmo -= 6 - this.bulletsAvailble;
        	this.bulletsAvailble = 6;
            return true;
        } else
            return false;
    }
    
    /**
     * Checks if player is fired a rocket. It also checks if player can 
     * fire a rocket (time between rockets, does a player have any rocket left).
     * 
     * @param gameTime The current elapsed game time in nanoseconds.
     * @return true if player is fired a rocket.
     */
    public boolean isFiredRocket(long gameTime)
    {
        // Checks if right mouse button is down && if it is the time for new rocket && if he has any rocket left.
        if( Canvas.mouseButtonState(MouseEvent.BUTTON3) && 
            ((gameTime - Rocket.timeOfLastCreatedRocket) >= Rocket.timeBetweenNewRockets) && 
            this.numberOfRockets > 0 ) 
        {
            return true;
        } else
            return false;
    }
    
    
    /**
     * Checks if player moving helicopter and sets its moving speed if player is moving.
     */
    public void isMoving()
    {
        // Moving on the x coordinate.
        if(Canvas.keyboardKeyState(KeyEvent.VK_D) || Canvas.keyboardKeyState(KeyEvent.VK_RIGHT))
	    		movingXspeed += acceleratingXspeed;
        else if(Canvas.keyboardKeyState(KeyEvent.VK_A) || Canvas.keyboardKeyState(KeyEvent.VK_LEFT))
        		movingXspeed -= acceleratingXspeed;
        else    // Stoping
            if(movingXspeed < 0)
                movingXspeed += stoppingXspeed;
            else if(movingXspeed > 0)
                movingXspeed -= stoppingXspeed;
        
        // Moving on the y coordinate.
        if(Canvas.keyboardKeyState(KeyEvent.VK_W) || Canvas.keyboardKeyState(KeyEvent.VK_UP))
        		movingYspeed -= acceleratingYspeed;
        else 
        	if(Canvas.keyboardKeyState(KeyEvent.VK_S) || Canvas.keyboardKeyState(KeyEvent.VK_DOWN))
	        		movingYspeed += acceleratingYspeed;
        else    // Stoping
            if(movingYspeed < 0)
                movingYspeed += stoppingYspeed;
            else if(movingYspeed > 0)
                movingYspeed -= stoppingYspeed;
        if( Canvas.keyboardKeyState(KeyEvent.VK_SPACE) && this.bulletsAvailble < 6) 
        {
        	this.numberOfAmmo -= 6 - this.bulletsAvailble;
        	this.bulletsAvailble = 6;
        }
    }
    
    
    /**
     * Updates position of helicopter, animations.
     */
    public void Update()
    {
	    if (xCoordinate < 5) {
	    	xCoordinate = 5;
	    	movingXspeed += acceleratingXspeed;
	    }	
	    if (xCoordinate + bodyImg.getWidth() > Framework.frameWidth - 5) {
	    	xCoordinate = Framework.frameWidth - bodyImg.getHeight() - 15;
    		movingXspeed -= acceleratingXspeed;
    	}	
	    if (yCoordinate < 5) {
	    	yCoordinate = 5;
	    	movingYspeed += acceleratingYspeed;
	    }
	    if (yCoordinate + bodyImg.getHeight() > Framework.frameHeight - 5) {
	    	yCoordinate = Framework.frameHeight - bodyImg.getHeight() - 5;
	    	movingYspeed -= acceleratingYspeed;
	    }
	    
	    // Move helicopter and its propellers.
        xCoordinate += movingXspeed;
        yCoordinate += movingYspeed;
        rearAnim.changeCoordinates(xCoordinate + offsetXRearPropeller, yCoordinate + offsetYRearPropeller);
        
        // Change position of the rocket holder.
        this.rocketHolderXcoordinate = this.xCoordinate + this.offsetXRocketHolder;
        this.rocketHolderYcoordinate = this.yCoordinate + this.offsetYRocketHolder;
        
        // Move the machine gun with helicopter.
        this.revolverXAnchor = this.xCoordinate + this.offsetXAnchor;
        this.revolverYAnchor = this.yCoordinate + this.offsetYAnchor;
    }
    
    
    /**
     * Draws helicopter to the screen.
     * 
     * @param g2d Graphics2D
     */
    public void Draw(Graphics2D g2d)
    {
        rearAnim.Draw(g2d);

        g2d.drawImage(frontImg, xCoordinate + offsetXFrontImg, yCoordinate + offsetYFrontImg, null);
        g2d.drawImage(bodyImg, xCoordinate, yCoordinate, null);
    }
    
}
